from mayan_cal import today
from mayan_cal.structure import Day
from mayan_cal.calculate import get_tribe_tone, get_guiding_power

class Template(object):
    STRING = \
'''I %(TONE_POWER)s in order to %(TRIBE_ACTION)s
%(TONE_ACTION_TENSED)s %(TRIBE_ESSENCE)s
I seal the %(TIMECELL)s of %(TRIBE_POWER)s
With the %(TONE_NAME)s tone of %(TONE_ESSENCE)s
I am guided by the power of %(GUIDING_POWER)s
'''

    # Are all these parts really necessary?  Not really; just use
    # Template.STRING % Affirmation(date).formatted_values
    class Part:
        def __init__(self, name):
            self.name = name
        def __mod__(self, values):
            return values[self.name]

    TONE_NAME          = Part('TONE_NAME')
    TONE_ACTION        = Part('TONE_ACTION')
    TONE_POWER         = Part('TONE_POWER')
    TONE_ESSENCE       = Part('TONE_ESSENCE')

    TONE_ACTION_TENSED = Part('TONE_ACTION_TENSED')

    TRIBE_ACTION       = Part('TRIBE_ACTION')
    TRIBE_POWER        = Part('TRIBE_POWER')
    TRIBE_ESSENCE      = Part('TRIBE_ESSENCE')

    TIMECELL           = Part('TIMECELL')
    GUIDING_POWER      = Part('GUIDING_POWER')

    NEWLINE = '\n'

    parts = ('I', TONE_POWER, 'in order to', TRIBE_ACTION, NEWLINE,
             TONE_ACTION_TENSED, TRIBE_ESSENCE, NEWLINE,
             'I seal the', TIMECELL, 'of', TRIBE_POWER, NEWLINE,
             'With the', TONE_NAME, 'tone of', TONE_ESSENCE, NEWLINE,
             'I am guided by the power of', GUIDING_POWER, NEWLINE)

    def __new__(self, values, kind = 'string'):
        if kind == 'string':
            return self.STRING % values
        if kind == 'parts':
            return (isinstance(p, self.Part) and p % values or p \
                    for p in self.parts)

TENSE = 'ing'
def tensed_word_form(action):
    # Create a grammatically correct word-form by stripping
    # trailing Es.
    i = len(action)
    while action[i - 1] in ('e', 'E'):
        i -= 1

    return action[:i] + TENSE

# XXX Action/Power TENSING

class Affirmation(Day):
    @property
    def values(self):
        return {'TONE_NAME'    : self.tone.name,
                'TONE_ACTION'  : self.tone.action,
                'TONE_POWER'   : self.tone.power,
                'TONE_ESSENCE' : self.tone.essence,

                'TONE_ACTION_TENSED': tensed_word_form(self.tone.action),

                'TRIBE_ACTION' : self.tribe.action,
                'TRIBE_POWER'  : self.tribe.power,
                'TRIBE_ESSENCE': self.tribe.essence,

                'TIMECELL'     : self.tribe.timecell.name,
                'GUIDING_POWER': self.guide}

    @property
    def formatted_values(self):
        return dict((n, str(v).upper()) for (n, v) in self.values.iteritems())

    @property
    def as_string(self):
        return Template(self.formatted_values, kind = 'string')

    @property
    def as_parts(self):
        return Template(self.formatted_values, kind = 'parts')

    def __str__(self):
        return self.as_string
    def __iter__(self):
        return self.as_parts

def daily_affirmation(day):
    tribe, tone = get_tribe_tone(day)
    guide = get_guiding_power(day)

    return Affirmation(day, tribe, tone, guide)

def todays_affirmation():
    return daily_affirmation(today())
